/***********************************************************************************
 * 文件名： polsys.h
 * 版本： 3
 * 说明：
 * 		polsys 核心实现。 
 *      【polsys】
 *      使用软定时器原理的“多任务”系统, 轮询调用入口函数，非RTOS。支持在任意地方创建任务。
 *      【polsys_lite】
 *      通过在用户端提供宏定义配置的方式让用户添加几个固定间隔时间需要执行的任务函数，然后在
 *  Polsys_Loop 定时调用他们。 这样的机制可以在不支持函数指针的“低端RISC 8位单片机”中帮助代
 *  码去耦，让软件更具模块化和面向对象。
 *      【通用说明】
 *      polsys_port.c 文件中已经编写好移植示例，详见该文件内的注释说明。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
 *  2021/05/19：合并polsys_lite。刘言。
 *  2021/11/15: 
 * 		定义 _POLSYS_DEBUG 后可以查看CPU使用率、是否过载等调试信息，每个TICK周期更新，过载
 * 	表示在一个TICK周期内不能执行完所有任务，一旦置位复位才能清除。
 * 		优化任务调度，现在只在有任务状态被标记为 TS_READY 后才会去扫描任务列表寻找并执行需要
 * 	执行的任务，其它时间都循环在执行 SYS_IDLE() 。刘言。
***********************************************************************************/
#ifndef _POLSYS_H_
#define _POLSYS_H_

#include <stddef.h>
#ifdef __NO_INCLUDE_PATH    // 如果有，定义在 stddef.h
#include "..\projects\prj\app\polsys_config.h"
#else
#include "polsys_config.h"
#endif
#include "polsys_mcu.h"


#ifdef POLSYS_LITE

// 仅为了伪函数优化曝光以下属性，用户不应该直接访问。

extern bit _Polsys_mTicked;
#ifdef _POLSYS_TASK_GROUP_1000TICK
extern u8 _Polsys_TickCount;
extern u8 _Polsys_10TickCount;
extern u8 _Polsys_100TickCount;
#elif (defined _POLSYS_TASK_GROUP_100TICK)
extern u8 _Polsys_TickCount;
extern u8 _Polsys_10TickCount;
#elif (defined _POLSYS_TASK_GROUP_10TICK)
extern u8 _Polsys_TickCount;
#endif

// 为了将 Polsys_Loop 函数定义成伪函数，才有了下面这一大推预处理

#if (defined _POLSYS_TASK_GROUP_10TICK)||(defined _POLSYS_TASK_GROUP_100TICK)||(defined _POLSYS_TASK_GROUP_1000TICK)
#ifdef _POLSYS_TASK_GROUP_10TICK
#define _Polsys_Do10TickTask()      _POLSYS_TASK_GROUP_10TICK
#else
#define _Polsys_Do10TickTask()
#endif
#if (defined _POLSYS_TASK_GROUP_100TICK)||(defined _POLSYS_TASK_GROUP_1000TICK)
#ifdef _POLSYS_TASK_GROUP_100TICK
#define _Polsys_Do100TickTask()      _POLSYS_TASK_GROUP_100TICK
#else
#define _Polsys_Do100TickTask()
#endif
#ifdef _POLSYS_TASK_GROUP_1000TICK
#define _Polsys_1000TickProcess()   \
{\
    _Polsys_100TickCount++;\
    if(_Polsys_100TickCount == 10)\
    {\
        _POLSYS_TASK_GROUP_1000TICK;\
        _Polsys_100TickCount = 0;\
    }\
}
#else
#define _Polsys_1000TickProcess()
#endif
#define _Polsys_100TickProcess()    \
{\
    _Polsys_10TickCount++;\
    if(_Polsys_10TickCount == 10)\
    {\
        _Polsys_Do100TickTask();\
        _Polsys_10TickCount = 0;\
        _Polsys_1000TickProcess();\
    }\
}
#else
#define _Polsys_100TickProcess()
#endif
#define _Polsys_10TickProcess() \
{\
    _Polsys_TickCount++;\
    if(_Polsys_TickCount == 10)\
    {\
        _Polsys_Do10TickTask();\
        _Polsys_TickCount = 0;\
        _Polsys_100TickProcess();\
    }\
}
#else
#define _Polsys_10TickProcess()
#endif


// APIs

#define Polsys_Init()   \
{\
    _Polsys_ClockInit();\
    _Polsys_TickStart();\
    Polsys_EnableInt();\
}

// 请在定时器中断中调用此函数
#define Polsys_Tick()   \
{   \
    _Polsys_mTicked = true;  \
}

// 在主循环中调用，用来执行各个任务
#define Polsys_Loop()   \
{\
    _POLSYS_TASK_GROUP_LOOP;\
    if (_Polsys_mTicked)\
    {\
        _Polsys_mTicked = false;\
        _POLSYS_TASK_GROUP_1TICK;\
        _Polsys_10TickProcess();\
    }\
}

#else

//自定义数据类型

// 任务状态
typedef enum _task_status
{
	TS_WAIT = 0,    // 执行时间未到
	TS_READY,        // 执行时间已经到了，即将被执行
    TS_RUNNING      // 任务正在被执行
} task_status_t;

// task “类”
typedef struct _polsys_task
{
    // 入口函数
	void (*EntryFunc)(void);
    // 运行间隔时间（软定时周期）
	u16 Interval;
    // 还需要等待的时间
	u16 WaitTime;
    // 状态
	task_status_t Status;
} polsys_task_t;

// 提供的接口

void Polsys_Init();
void Polsys_Tick(); //在定时器中调用，规定调用间隔1ms
void Polsys_Loop(); //在主循环调用

// 初始化一个任务，这个任务会被加入到任务列表
// task_ptr: 任务对象的地址，需要先静态定义一个task对象（polsys_task_t）
// Entry: 任务入口函数
// Interval: 执行间隔时间，以 POLSYS_TICK_CYCLE 为单位，不建议为0。
// 注意：同一个任务只能被初始化一次。
bool Polsys_TaskInit(polsys_task_t *task_ptr, void (*Entry)(void), u16 Interval);

// 动态创建一个任务。【待实现】
// polsys_task_t *Polsys_NewTask(void (*Entry)(void), u16 Interval);

// 动态删除一个任务，只能删除动态创建的任务。【待实现】
// Polsys_DeleteTask(polsys_task_t *task_ptr);
#endif

#include "polsys_cpts.h"

#endif
